package com.fasteat.mall.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasteat.common.entity.Result;
import com.fasteat.mall.entity.Product;
import com.fasteat.mall.entity.VisitedHistory;
import com.fasteat.mall.mapper.ProductMapper;
import com.fasteat.mall.service.ProductService;
import com.fasteat.mall.service.VisitedHistoryService;
import com.fasteat.mall.service.client.ProductSearchClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author hy 、ghost
 * @since 2021-01-19
 */
@RestController
@Api(description = "商品后台接口")
@RequestMapping("/mall/product")
@CrossOrigin
public class ProductController {

	@Autowired
	private ProductService productService;

	@Autowired
	private ExecutorService threadPool;

	@Autowired
	private ProductSearchClient productSearchClient;

	@Autowired
	private ProductMapper productMapper;

	@Autowired
	private VisitedHistoryService visitedHistoryService;


	/**
	 * 返回销量前10的商品
	 *
	 * @return
	 */
	@GetMapping("salesVolume")
	@ApiOperation("返回销量前10的商品")
	public Result salesVolume() {
		Page<Product> page = new Page(1, 10);
		QueryWrapper wrapper = new QueryWrapper();
		wrapper.orderByDesc("sales_volume");
		productService.page(page, wrapper);
		return Result.success().data(page);
	}

	/**
	 * 返回新品前10的商品
	 *
	 * @return
	 */
	@GetMapping("gmtCreateSalesVolume")
	@ApiOperation("返回新品前10的商品")
	public Result gmtCreateSalesVolume() {
		Page<Product> page = new Page(1, 10);
		QueryWrapper wrapper = new QueryWrapper();
		wrapper.orderByDesc("gmt_create");
		wrapper.orderByDesc("sales_volume");
		productService.page(page, wrapper);
		return Result.success().data(page);
	}
	//

	/**
	 * 返回好评前10的商品
	 *
	 * @return
	 */
	@GetMapping("goodComment")
	@ApiOperation("返回好评前10的商品")
	public Result goodComment() {
		productMapper.selectUnionOtherTable();
		return Result.success().data(productService.listTenGoodCommentProduct());
	}

	/**
	 * 新增商品
	 *
	 * @param product
	 * @return
	 */
	@ApiOperation(value = "新增商品信息")
	@PostMapping("/save")
	public Result saveProduct(@RequestBody
							  @ApiParam(value = "商品product对象", required = true)
									  Product product) {
		if (product == null) {
			return Result.error("添加失败");
		}
		boolean result = productService.save(product);
		return result
				?
				Result.success("添加成功")
				:
				Result.error("添加失败");
	}

	/**
	 * 修改商品信息
	 *
	 * @param product
	 * @return
	 */
	@PutMapping("/update")
	@ApiOperation(value = "根据商品id修改商品信息")
	public Result updateProduct(@RequestBody
								@ApiParam(value = "商品product对象", required = true)
										Product product) {
		if (StringUtils.isEmpty(product.getId())) {
			return Result.error("修改失败");
		}
		boolean result = productService.updateById(product);
		return result
				?
				Result.success()
				:
				Result.error("修改失败");
	}

	/**
	 * 查看所有商品
	 *
	 * @return
	 */
	@GetMapping("/findAll")
	@ApiOperation("获取所有商品信息(上下架)")
	public Result selectProductListAll() {

		return Result.success("查询成功").data(productService.list(null));
	}

	/**
	 * 查看所有上架商品
	 *
	 * @return
	 */
	@GetMapping("/findAllOnSale")
	@ApiOperation("获取所有商品信息(上架)")
	public Result selectProductListOnSale() {
		QueryWrapper<Product> wrapper = new QueryWrapper<>();
		wrapper.eq("status", 1);
		List<Product> productList = productService.list(wrapper);
		return Result.success("查询成功").data(productList);
	}

	/**
	 * 分页查看所有上架商品
	 *
	 * @return
	 */
	@GetMapping("/findAllOnSale/{current}/{size}")
	@ApiOperation("分页获取所有商品信息(上架)")
	public Result selectProductListOnSalePage(@PathVariable(name = "size")
											  @ApiParam(required = true, value = "尺寸")
													  int size,
											  @PathVariable(name = "current")
											  @ApiParam(required = true, value = "当前页码")
													  int current) {
		QueryWrapper<Product> wrapper = new QueryWrapper<>();
		wrapper.eq("status", 1);
		size = size <= 0 ? 5 : size;
		current = current <= 0 ? 1 : current;
		Page<Product> page = new Page<>(current, size);
		IPage<Product> productList = productService.page(page, wrapper);
//        List<Product> productList = productService.list(wrapper);
		return Result.success("查询成功").data(productList);
	}

	/**
	 * 分页分类查询上架商品
	 *
	 * @return
	 */
	@GetMapping("/findOneTypeOnSale/{sort}/{current}/{size}")
	@ApiOperation("分页分类获取所有商品信息(上架)")
	public Result selectOneTypeProductListOnSalePage(@PathVariable(name = "sort")
													 @ApiParam(required = true, value = "类别") int sort,
													 @PathVariable(name = "size")
													 @ApiParam(required = true, value = "尺寸")
															 int size,
													 @PathVariable(name = "current")
													 @ApiParam(required = true, value = "当前页码")
															 int current) {
		QueryWrapper wrapper = new QueryWrapper<>();
		wrapper.eq("status", 1);
		wrapper.eq("sort", sort);
		size = size <= 0 ? 5 : size;
		current = current <= 0 ? 1 : current;
		Page<Product> page = new Page<>(current, size);
		productService.page(page, wrapper);
		return Result.success("查询成功").data(page);
	}

	/**
	 * 查看所有下架商品
	 *
	 * @return
	 */
	@GetMapping("/findAllOutofSale")
	@ApiOperation("获取所有商品信息(下架)")
	public Result selectProductListOutofSale() {
		QueryWrapper<Product> wrapper = new QueryWrapper<>();
		wrapper.eq("status", 0);
		List<Product> productList = productService.list(wrapper);
		return Result.success("查询成功").data(productList);
	}

	/**
	 * 分页查看所有下架商品
	 *
	 * @return
	 */
	@GetMapping("/findAllOutofSale/{current}/{size}")
	@ApiOperation("分页获取所有商品信息(下架)")
	public Result selectProductListOutofSalePage(@PathVariable(name = "size")
												 @ApiParam(required = true, value = "尺寸")
														 int size,
												 @PathVariable(name = "current")
												 @ApiParam(required = true, value = "当前页码")
														 int current) {
		QueryWrapper<Product> wrapper = new QueryWrapper<>();
		wrapper.eq("status", 0);
		size = size <= 0 ? 5 : size;
		current = current <= 0 ? 1 : current;
		Page<Product> page = new Page<>(current, size);
		IPage<Product> productList = productService.page(page, wrapper);
//        List<Product> productList = productService.list(wrapper);
		return Result.success("查询成功").data(productList);
	}

	/**
	 * 通过商品ID获取商品信息
	 *
	 * @param productId
	 * @param userId
	 * @return
	 */
	@GetMapping("findById/{productId}/{userId}")
	@ApiOperation("通过商品ID获取商品信息")
	public Result findById(@PathVariable(name = "productId", required = true)
						   @ApiParam(value = "商品ID", required = true) String productId,
						   @PathVariable(name = "userId")
						   @ApiParam(value = "用户ID") String userId) {
		if (StringUtils.isEmpty(productId)) {
			return Result.error("查询失败");
		}
		// 从数据库中查询商品的信息
		Product product = productService.getById(productId);
		if (product == null) {
			return Result.error("查询失败");
		} else {
			// 记录用户浏览商品记录，当用户id为null时不记录，即用户未登录
			if (!StringUtils.isEmpty(userId) && !userId.equals("{userId}")) {
				// 开启异步线程，进行慢写操作
				CompletableFuture.runAsync(() -> {
					visitedHistoryService.save(new VisitedHistory(userId,
							productId, product.getSort(), product.getSalesVolume()));
				});
			}
			return Result.success().data(product);
		}
	}

	/**
	 * 通过商品名称获取商品信息
	 *
	 * @param productTitle
	 * @return
	 */
	@GetMapping("findByTitle/{productTitle}/{size}/{current}")
	@ApiOperation("通过商品名称获取商品信息")
	public Result findByName(@PathVariable(name = "size")
							 @ApiParam(required = true, value = "尺寸")
									 int size,
							 @PathVariable(name = "current")
							 @ApiParam(required = true, value = "当前页码")
									 int current,
							 @PathVariable(name = "productTitle", required = true)
							 @ApiParam(value = "商品ID", required = true)
									 String productTitle) {
		if (StringUtils.isEmpty(productTitle)) {
			return Result.error("查询失败");
		}
		// 从数据库中查询商品的信息
		size = size <= 0 ? 5 : size;
		current = current <= 0 ? 1 : current;
		Page<Product> page = new Page(current, size);
		QueryWrapper<Product> wrapper = new QueryWrapper<>();
		wrapper.like("title", productTitle);
		productService.page(page, wrapper);
		return Result.success().data(page);
	}

	/**
	 * 分页查看商品
	 *
	 * @return
	 */
	@GetMapping("/{size}/{current}")
	@ApiOperation("分页查看商品")
	public Result acceptProduct(@PathVariable(name = "size") @ApiParam(required = true, value = "尺寸") int size,
								@PathVariable(name = "current") @ApiParam(required = true, value = "当前页码") int current) {
		size = size <= 0 ? 5 : size;
		current = current <= 0 ? 1 : current;
		Page<Product> page = new Page(current, size);
		QueryWrapper wrapper = new QueryWrapper();
		wrapper.orderByDesc("gmt_create");
		productService.page(page, wrapper);
		return Result.success().data(page);
	}

	/**
	 * 分页分类别查看商品
	 *
	 * @param size
	 * @param current
	 * @param sort
	 * @return
	 */
	@GetMapping("/{size}/{current}/{sort}")
	@ApiOperation("分页分类别查看商品")
	public Result findBySortPage(@PathVariable(name = "size") @ApiParam(required = true, value = "尺寸") int size,
								 @PathVariable(name = "current") @ApiParam(required = true, value = "当前页码") int current,
								 @PathVariable(name = "sort") @ApiParam(required = true, value = "分类") Integer sort) {

		size = size <= 0 ? 5 : size;
		current = current <= 0 ? 1 : current;
		Page<Product> page = new Page<>(current, size);
		QueryWrapper<Product> wrapper = new QueryWrapper<>();
		if (!StringUtils.isEmpty(sort)) {
			wrapper.eq("sort", sort);
		}
		productService.page(page, wrapper);
		//拿到总记录数
		long total = page.getTotal();
		//数据list集合
		List<Product> productList = page.getRecords();
		return Result.success("查询成功").data(total).data(productList);
	}

	/**
	 * 按类别查找商品
	 *
	 * @param sort
	 * @return
	 */
	@GetMapping("/{sort}")
	@ApiOperation(value = "按类别查找商品")
	public Result findBySort(@PathVariable(name = "sort") @ApiParam(required = true, value = "类别") Integer sort) {
		QueryWrapper<Product> wrapper = new QueryWrapper<>();
		wrapper.eq("sort", sort);
		List<Product> productList = productService.list(wrapper);
		long total = productList.size();
		return Result.success("查询成功").data(total).data(productList);
	}

	/**
	 * 根据id删除商品
	 *
	 * @param productId
	 * @return
	 */
	@DeleteMapping(value = "/delete/{productId}")
	@ApiOperation(value = "根据商品id删除商品")
	public Result deleteById(@PathVariable(name = "productId", required = true)
							 @ApiParam(value = "productId", required = true)
									 String productId) {
		if (productId == null) {
			return Result.error("删除失败");
		}
		threadPool.submit(() -> productSearchClient.deleteProductById(productId));
		boolean result = productService.removeById(productId);
		return result ?
				Result.success("删除成功")
				:
				Result.error("删除失败");
	}

	/**
	 * 上架接口
	 *
	 * @param productId
	 * @return
	 */
	@ApiOperation(value = "上架接口")
	@PutMapping("/inSale/{productId}")
	public Result inSaleProduct(@PathVariable(name = "productId", required = true)
								@ApiParam(value = "productId", required = true)
										String productId) {
		Product product = productService.getById(productId);
		if (StringUtils.isEmpty(product.getId())) {
			return Result.error("商品id为空");
		}
		product.setStatus(1);
		boolean result = productService.updateById(product);
		return result ? Result.success("上架成功") : Result.error("上架失败");
	}

	/**
	 * 下架接口
	 *
	 * @param productId
	 * @return
	 */
	@ApiOperation(value = "下架接口")
	@PutMapping("/outOfSale/{productId}")
	public Result outOfSaleProduct(@PathVariable(name = "productId", required = true)
								   @ApiParam(value = "productId", required = true)
										   String productId) {
		Product product = productService.getById(productId);
		if (StringUtils.isEmpty(product.getId())) {
			return Result.error("商品id为空");
		}
		product.setStatus(0);
		boolean result = productService.updateById(product);
		return result ? Result.success("下架成功") : Result.error("下架失败");
	}

	/**
	 * 同城推荐
	 *
	 * @param province
	 * @param city
	 * @return
	 */
	@GetMapping("/sameCity")
	@ApiOperation(value = "同城推荐")
	public Result sameCity(String province, String city) {
		QueryWrapper<Product> wrapper = new QueryWrapper<>();
		wrapper.eq("province", province);
		wrapper.eq("city", city);
		wrapper.orderByDesc("gmt_create");
		Page<Product> page = new Page(1, 10);
		productService.page(page, wrapper);
		return Result.success().data(page);
	}
}

